package com.lili.collection.core.serializer;

import com.lili.collection.core.support.ConfigFieldDef;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * GlobalConfigDefPropertyUtil
 *
 * @author lili
 * @date 2023/2/28 17:38
 */
public class GlobalConfigDefPropertyUtil {
    private final static Map<Class, Map<String, Field>> MAP = new HashMap<>();

    public static Map<String, Field> getFieldMap(Object instance) {
        Map<String, Field> fieldMap = null;
        if (MAP.containsKey(instance.getClass()))
            fieldMap = MAP.get(instance.getClass());
        else {
            synchronized (GlobalConfigDefPropertyUtil.class) {
                if (MAP.containsKey(instance.getClass()))
                    fieldMap = MAP.get(instance.getClass());
                else {
                    fieldMap = new HashMap<>();
                    Field[] declaredFields = instance.getClass().getDeclaredFields();
                    for (Field declaredField : declaredFields) {
                        boolean annotationPresent = declaredField.isAnnotationPresent(ConfigFieldDef.class);
                        if (annotationPresent)
                            fieldMap.put(declaredField.getName(), declaredField);
                    }
                    MAP.put(instance.getClass(), fieldMap);
                }
            }
        }
        return fieldMap;
    }

    public static boolean containsField(Object instance, String name) {
        Map<String, Field> fieldMap = getFieldMap(instance);
        return fieldMap.containsKey(name);
    }

    public static Field getField(Object instance, String name) {
        if (!containsField(instance, name)) return null;
        Map<String, Field> fieldMap = getFieldMap(instance);
        return fieldMap.get(name);
    }

    public static ConfigFieldDef getFieldDef(Object instance, String name) {
        Field field = getField(instance, name);
        if (field == null) return null;
        ConfigFieldDef fieldDef = field.getDeclaredAnnotation(ConfigFieldDef.class);
        return fieldDef;
    }
}
